Api Server 部分使用 apollographql + Mongo 設定方式檔案如下
比較要注意的部分是 config的部分 因為 server跟 client分開來所以要加上cros的設定 要注意 origin 的設定
const express = require('express')
const cors = require('cors')
const bodyParser = require('body-parser')
const cookieSession = require('cookie-session')
const config = require('./config')
const mongoose = require('./mongoose')
mongoose.connect(config.mongoURI)
require('./src/models')
const schema = require('./src')
const {
apolloMiddleInterFace,
apolloMiddle
} = require('./middleware/apolloMiddle')
require('./config/seed/index')
const port = process.env.PORT || 8080
const server = express()
server.use(cors({ credentials: true, origin: config.origin }))
server.use(bodyParser.json())
server.use(bodyParser.urlencoded({ extended: true }))
server.use(
cookieSession({
maxAge: 30 * 24 * 60 * 60 * 1000,
keys: [config.cookieKey],
secure: config.production
})
)
apolloMiddle(server, schema)
apolloMiddleInterFace(server)
server.listen(port, err => {
if (err) throw err
// eslint-disable-next-line no-console
console.log(`> ready on http://localhost:${port}`)
})
config檔案 這邊會再區分 上線版本與開發版本的config
module.exports = {
production: false,
origin: 'http://localhost:3000',
mongoURI: 'mongodb://mongo:27017/erp-system',
cookieKey: '',
secret: ''
}
mongo 部分 先建立連線 並且把所有的model有引用進來
const mongoose = require('./mongoose')
mongoose.connect(config.mongoURI)
require('./src/models')
這邊的require('./src/models') 會把該目錄的都一次載入如下
var normalizedPath = require('path').join(__dirname)
require('fs')
.readdirSync(normalizedPath)
.forEach(function(file) {
if (file !== 'fragment') {
require('./' + file)
}
})
mongo 部分則是使用docker 比較快就可以開始開發
apollographql部分 建立
apolloMiddle(server, schema)
apolloMiddleInterFace(server)
兩個middleware 一個是處理 payload對應 與 schema的地方 另外一個用來做一些共同行為的處理
在對應部分設定 除了server.use( '/graphql',.... 這是對應graphql server的位置之外還會設定一個
server.use('/graphiql',.... 差別在一個小i 這個 graphiqlExpress apollographql提供的網頁介面查詢測試語法的介面
const { graphqlExpress, graphiqlExpress } = require('apollo-server-express')
const bodyParser = require('body-parser')
const mongoLog = require('../middleware/mongoLog')
const apolloMiddle = (server, schema) =>
server.use(
'/graphql',
bodyParser.json(),
graphqlExpress(req => ({
schema,
context: { req },
async formatResponse(data) {
if (!data.errors) await mongoLog(req)
return data
}
}))
)
const apolloMiddleInterFace = server => {
server.use(
'/graphiql',
graphiqlExpress({
endpointURL: '/graphql'
})
)
}
module.exports = { apolloMiddle, apolloMiddleInterFace }
另外一隻middleware 會用來做一些log紀錄 或是共用行為的處理
const { getUserId } = require('../src/utils')
const Log = require('../src/models/log')
const User = require('../src/models/user')
const mongoLog = async req => {
if (req.originalUrl === '/graphql') {
if (req.body.query.includes('mutation')) {
if (req.body.operationName === 'login') {
const user = await User.findOne({ account: req.body.variables.account })
const log = new Log({
operationName: req.body.operationName,
body: JSON.stringify(req.body),
createUserId: user._id
})
await log.save()
} else {
const userId = getUserId({ req }, false)
const log = new Log({
operationName: req.body.operationName,
body: JSON.stringify(req.body),
createUserId: userId
})
await log.save()
}
}
}
}
module.exports = mongoLog
總結
server端的環境就是要注意的有 cros 跨區, 還有 apollograpqhl,mongo的連結設定